package xx.iverson.school_manage.controller;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import xx.iverson.school_manage.entity.OperationRecord;
import xx.iverson.school_manage.entity.User;
import xx.iverson.school_manage.service.OperationRecordService;
import xx.iverson.school_manage.service.UserService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @author wei77
 */
@Controller
public class OperationRecordController {

    @Resource
    private OperationRecordService operationRecordService;

    @Resource
    private UserService userService;

    // 根据用户id和月份查询操作记录
    @RequestMapping("/findByMonth")
    @ResponseBody
    public List<OperationRecord> findOperationRecordsByMonth(HttpServletRequest request, HttpSession session) {
        return operationRecordService.findOperationRecordsByMonth(Integer.parseInt(request.getParameter("year")), Integer.parseInt(request.getParameter("month")), ((User) session.getAttribute("user")).getUserId());
    }

    @RequestMapping(value = "/exportRecords", method = RequestMethod.GET)
    @ResponseBody
    public void exportRecords(@RequestParam("startDate") int startDate,
                              @RequestParam("endDate") int endDate,
                              @RequestParam("userId") int userId,
                              HttpServletResponse response) throws IOException {

        List<OperationRecord> records;
        if (startDate == 0 && endDate == 0) {
            records = operationRecordService.exportOperationRecordsByMonth(20200101, 20300101, userId);
            // 调用服务层获取数
            User user = userService.getUserByUserId(userId);
            ByteArrayOutputStream outputStream = generateExcel(records);
            // 设置正确的 Content-Type

            response.setContentType("application/vnd.ms-excel");
            String encodedFileName = URLEncoder.encode(user.getRealName() + "全部操作记录.xlsx", StandardCharsets.UTF_8.name());
            response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName.replace("+", "%20"));
            OutputStream out = response.getOutputStream();
            out.write(outputStream.toByteArray());
            out.flush();
        } else {
            records = operationRecordService.exportOperationRecordsByMonth(startDate, endDate, userId);
            // 调用服务层获取数
            User user = userService.getUserByUserId(userId);
            ByteArrayOutputStream outputStream = generateExcel(records);
            // 设置正确的 Content-Type

            response.setContentType("application/vnd.ms-excel");
            String encodedFileName = URLEncoder.encode(getFormattedFileName(user.getRealName(), startDate, endDate), StandardCharsets.UTF_8.name());
            response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName.replace("+", "%20"));
            OutputStream out = response.getOutputStream();
            out.write(outputStream.toByteArray());
            out.flush();
        }


    }

    private String getFormattedFileName(String realName, int startDate, int endDate) {
        return realName + "_" + startDate + "——" + endDate + ".xlsx";
    }

    private ByteArrayOutputStream generateExcel(List<OperationRecord> records) throws IOException {
        // 创建Excel工作簿
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("操作记录");

        // 设置列宽
        sheet.setColumnWidth(0, 20 * 256); // 操作人
        sheet.setColumnWidth(1, 10 * 256); // 类型
        sheet.setColumnWidth(2, 15 * 256); // 操作积分
        sheet.setColumnWidth(3, 15 * 256); // 操作前积分
        sheet.setColumnWidth(4, 15 * 256); // 操作后积分
        sheet.setColumnWidth(5, 30 * 256); // 操作时间
        sheet.setColumnWidth(6, 30 * 256); // 备注

        // 创建表头样式
        XSSFCellStyle headerStyle = workbook.createCellStyle();
        headerStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

        // 创建表头字体样式
        XSSFFont font = workbook.createFont();
        font.setBold(true);
        headerStyle.setFont(font);

        // 创建表头
        XSSFRow headerRow = sheet.createRow(0);
        XSSFCell cell = headerRow.createCell(0);
        cell.setCellValue("操作人");
        cell.setCellStyle(headerStyle);

        cell = headerRow.createCell(1);
        cell.setCellValue("类型");
        cell.setCellStyle(headerStyle);

        cell = headerRow.createCell(2);
        cell.setCellValue("操作积分");
        cell.setCellStyle(headerStyle);

        cell = headerRow.createCell(3);
        cell.setCellValue("操作前积分");
        cell.setCellStyle(headerStyle);

        cell = headerRow.createCell(4);
        cell.setCellValue("操作后积分");
        cell.setCellStyle(headerStyle);

        cell = headerRow.createCell(5);
        cell.setCellValue("操作时间");
        cell.setCellStyle(headerStyle);

        cell = headerRow.createCell(6);
        cell.setCellValue("备注");
        cell.setCellStyle(headerStyle);

        // 填充数据
        int rowIndex = 1;
        for (OperationRecord record : records) {
            XSSFRow row = sheet.createRow(rowIndex++);
            XSSFCell cellData = row.createCell(0);
            cellData.setCellValue(record.getOperator());

            cellData = row.createCell(1);
            cellData.setCellValue(record.getOperationType() == 1 ? "减少" : "增加");

            cellData = row.createCell(2);
            cellData.setCellValue(record.getOperationType() == 1 ? "-" + record.getOperatorPoints() : "+" + record.getOperatorPoints());

            cellData = row.createCell(3);
            cellData.setCellValue(record.getOldPoints());

            cellData = row.createCell(4);
            cellData.setCellValue(record.getNewPoints());

            cellData = row.createCell(5);
            cellData.setCellValue(record.getOperationTime().toString());

            cellData = row.createCell(6);
            cellData.setCellValue(record.getNotes());
        }

        // 将工作簿写入字节数组输出流
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        workbook.write(outputStream);
        workbook.close();

        return outputStream;
    }

    @RequestMapping(value = "/exportMultipleRecords", method = RequestMethod.GET)
    @ResponseBody
    public void exportMultipleRecords(@RequestParam("startDate") int startDate,
                                      @RequestParam("endDate") int endDate,
                                      @RequestParam("userIds") List<Integer> userIds,
                                      HttpServletResponse response) throws IOException {
        if(userIds.get(0)==0){
            userIds=userService.getAllUserIds();
        }
        HashMap<String,List<OperationRecord>> records = operationRecordService.exportMultipleOperationRecordsByMonth(startDate, endDate, userIds);

        ByteArrayOutputStream outputStream = generateMultipleExcel(records);

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        String encodedFileName = URLEncoder.encode("操作记录-" + startDate + "——" + endDate + ".xlsx", StandardCharsets.UTF_8.name());
        response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName.replace("+", "%20"));

        OutputStream out = response.getOutputStream();
        out.write(outputStream.toByteArray());
        out.flush();
    }

    private ByteArrayOutputStream generateMultipleExcel(HashMap<String, List<OperationRecord>> records) throws IOException {
        XSSFWorkbook workbook = new XSSFWorkbook();

        // 创建Excel工作簿
        for (Map.Entry<String, List<OperationRecord>> entry : records.entrySet()) {
            String sheetName = entry.getKey();
            List<OperationRecord> recordList = entry.getValue();
            XSSFSheet sheet = workbook.createSheet(sheetName);

            // 设置列宽
            sheet.setColumnWidth(0, 20 * 256); // 操作人
            sheet.setColumnWidth(1, 10 * 256); // 类型
            sheet.setColumnWidth(2, 15 * 256); // 操作积分
            sheet.setColumnWidth(3, 15 * 256); // 操作前积分
            sheet.setColumnWidth(4, 15 * 256); // 操作后积分
            sheet.setColumnWidth(5, 30 * 256); // 操作时间
            sheet.setColumnWidth(6, 30 * 256); // 备注

            // 创建表头样式
            XSSFCellStyle headerStyle = workbook.createCellStyle();
            headerStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
            headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

            // 创建表头字体样式
            XSSFFont font = workbook.createFont();
            font.setBold(true);
            headerStyle.setFont(font);

            // 创建表头
            XSSFRow headerRow = sheet.createRow(0);
            XSSFCell cell = headerRow.createCell(0);
            cell.setCellValue("操作人");
            cell.setCellStyle(headerStyle);
            cell = headerRow.createCell(1);
            cell.setCellValue("类型");
            cell.setCellStyle(headerStyle);
            cell = headerRow.createCell(2);
            cell.setCellValue("操作积分");
            cell.setCellStyle(headerStyle);
            cell = headerRow.createCell(3);
            cell.setCellValue("操作前积分");
            cell.setCellStyle(headerStyle);
            cell = headerRow.createCell(4);
            cell.setCellValue("操作后积分");
            cell.setCellStyle(headerStyle);
            cell = headerRow.createCell(5);
            cell.setCellValue("操作时间");
            cell.setCellStyle(headerStyle);
            cell = headerRow.createCell(6);
            cell.setCellValue("备注");
            cell.setCellStyle(headerStyle);

            // 填充数据
            int rowIndex = 1;
            for (OperationRecord record : recordList) {
                XSSFRow row = sheet.createRow(rowIndex++);
                XSSFCell cellData = row.createCell(0);
                cellData.setCellValue(record.getOperator());
                cellData = row.createCell(1);
                cellData.setCellValue(record.getOperationType() == 1 ? "减少" : "增加");
                cellData = row.createCell(2);
                cellData.setCellValue(record.getOperationType() == 1 ? "-" + record.getOperatorPoints() : "+" + record.getOperatorPoints());
                cellData = row.createCell(3);
                cellData.setCellValue(record.getOldPoints());
                cellData = row.createCell(4);
                cellData.setCellValue(record.getNewPoints());
                cellData = row.createCell(5);
                cellData.setCellValue(record.getOperationTime().toString());
                cellData = row.createCell(6);
                cellData.setCellValue(record.getNotes());
            }
        }

        // 将工作簿写入字节数组输出流
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        workbook.write(outputStream);
        workbook.close();

        return outputStream;
    }

    // 添加增加积分的操作记录
    @RequestMapping("/addIncreaseOperationRecord")
    @ResponseBody
    public boolean addIncreaseOperationRecord(@RequestParam Integer userId,
                                              @RequestParam Integer operatorPoints,
                                              @RequestParam String notes, HttpSession session) {
        OperationRecord operationRecord = createOperationRecord(session, userId, operatorPoints, notes);
        return operationRecordService.addIncreaseOperationRecord(operationRecord);
    }

    // 添加减少积分的操作记录
    @RequestMapping("/addDecreaseOperationRecord")
    @ResponseBody
    public boolean addDecreaseOperationRecord(@RequestParam Integer userId,
                                              @RequestParam Integer operatorPoints,
                                              @RequestParam String notes, HttpSession session) {
        OperationRecord operationRecord = createOperationRecord(session, userId, operatorPoints, notes);
        return operationRecordService.addDecreaseOperationRecord(operationRecord);
    }

    // 批量添加增加积分的操作记录
    @RequestMapping(value = "/batchAddIncreaseOperationRecord", method = RequestMethod.POST)
    @ResponseBody
    public boolean batchAddIncreaseOperationRecord(@RequestBody BatchOperationRequest request, HttpSession session) {
        List<OperationRecord> operationRecords = createOperationRecords(session, request.getUserIds(), request.getOperatorPoints(), request.getNotes());
        return operationRecordService.batchAddIncreaseOperationRecord(operationRecords);
    }

    // 批量添加减少积分的操作记录
    @RequestMapping(value = "/batchAddDecreaseOperationRecord", method = RequestMethod.POST)
    @ResponseBody
    public boolean batchAddDecreaseOperationRecord(@RequestBody BatchOperationRequest request, HttpSession session) {
        List<OperationRecord> operationRecords = createOperationRecords(session, request.getUserIds(), request.getOperatorPoints(), request.getNotes());
        return operationRecordService.batchAddDecreaseOperationRecord(operationRecords);
    }

    @RequestMapping("/allUserIds")
    @ResponseBody
    public List<Integer> getAllUserIds() {
        return userService.getAllUserIds();
    }

    // 创建一个辅助方法来构建和收集OperationRecord列表
    private List<OperationRecord> createOperationRecords(HttpSession session, List<Integer> userIds, Integer operatorPoints, String notes) {
        User user = (User) session.getAttribute("user");
        return userIds.stream()
                .map(userId -> {
                    return getOperationRecord(userId, operatorPoints, notes, user);
                })
                .collect(Collectors.toList());
    }

    //创建一个方法来构建和收集OperationRecord
    private OperationRecord createOperationRecord(HttpSession session, Integer userId, Integer operatorPoints, String notes) {
        User user = (User) session.getAttribute("user");
        return getOperationRecord(userId, operatorPoints, notes, user);
    }

    private OperationRecord getOperationRecord(Integer userId, Integer operatorPoints, String notes, User user) {
        OperationRecord record = new OperationRecord();
        record.setUserId(userId);
        record.setOperator(user.getRealName());
        record.setOperationAccount(String.valueOf(user.getUserId()));
        record.setOperatorPoints(operatorPoints);
        record.setNotes(notes);
        return record;
    }

    // 新增一个类来封装请求体数据
    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    public static class BatchOperationRequest {
        private List<Integer> userIds;
        private Integer operatorPoints;
        private String notes;
    }

}
